package org.zn.mvcbase.exception;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.zn.commons.collection.Maps;
import org.zn.mvcbase.common.utilities.ClasspathPackageScanner;

import com.google.common.base.Strings;

/**
 * 
 * @author 周楠
 * @Description:
 *
 * @date 2017年7月26日
 *
 */

public class ExceptionResponseMessageFactory {

	private  List<String> ermRegist;

	private String[] ermPackage;

	private Map<Class<? extends Throwable>, ExceptionResponseMessage> ermMapping = Maps.newMap();

	public ExceptionResponseMessageFactory(String...ermPackage) {
		// TODO Auto-generated constructor stub
		this.ermPackage=ermPackage;
	}
	
	
	
	private boolean ermPackageCheck() {
		
		boolean b= ermPackage!=null && ermPackage.length>0;
		
		if(b) {
			
			for (String ep : ermPackage) {
				if(Strings.isNullOrEmpty(ep)) b=false;
			}
			
		}
		return b;
		
	}
	
	
	@PostConstruct
	public void init() {

		if (ermPackageCheck()) {

		ermRegist = new ArrayList<>();
		ClasspathPackageScanner ps = new ClasspathPackageScanner(ermPackage);
		
		try {
			ermRegist.addAll(ps.getFullyQualifiedClassNameList());

			for (String string : ermRegist) {

				Class<? extends ExceptionResponseMessage> clazz = (Class<? extends ExceptionResponseMessage>) Class
						.forName(string);

				ExceptionType et = clazz.getAnnotation(ExceptionType.class);

				Class<? extends Throwable>[] etvalue = et.value();

				ExceptionResponseMessage erm = clazz.newInstance();

				for (Class<? extends Throwable> taclazz : etvalue) {

					ermMapping.put(taclazz, erm);

				}

			}

			} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			}
		}
		
		
		ermMapping.put(null, new DefaultExceptionResponseMessage());

	}
	
	
	public ExceptionResponseMessage getExceptionResponseMessage(Throwable ex) {
		
		ExceptionResponseMessage erm=ermMapping.get(ex.getClass());
		
		if(erm==null) {
			erm=ermMapping.get(null);
		}
		
		
		return erm;
		
	}
	

}
